﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Configuration;

namespace BoAddonBiz_FreightForwarder
{
    internal class Log:IDisposable
    {
        private static Queue<String> MessageQueue;
        private static StreamWriter sw;
        private static bool ThreadState;
        private static object mylock = new object();
        private static Log instance;
        private Log()
        {
            if (MessageQueue == null)
            {
                ThreadState = true;
                MessageQueue = new Queue<string>();
                Thread LogThread = new Thread(new ThreadStart(DoWork));
                LogThread.Start();
            }
        }
        public static Log GetInstance()
        {
            if (instance == null)
                lock (mylock)
                {
                    if (instance == null)
                        instance = new Log();
                }
            return instance;
        }
        public void Write(string Message)
        {
            try
            {
                if (sw == null)
                {
                    lock (mylock)
                    {
                        OpenFile();
                    }
                }
                sw.WriteLine("*****************************************************************");
                sw.WriteLine("Datatime：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"));
                sw.WriteLine("Message：" + Message);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex);
            }
        }
        public void Write(Exception Message)
        {
            try
            {
                if (sw == null)
                {
                    lock (mylock)
                    {
                        OpenFile();
                    }
                }
                sw.WriteLine("*****************************************************************");
                sw.WriteLine("Datatime：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"));
                sw.WriteLine("Message：" + Message.Message);
                sw.WriteLine("Source：" + Message.Source);
                sw.WriteLine("StackTrace：" + Message.StackTrace);
                sw.WriteLine("TargetSite：" + Message.TargetSite);
                sw.Flush();
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(ex);
            }
        }
        private void DoWork()
        {
            while (true)
            {
                if (MessageQueue.Count > 0)
                {
                    string Message = null;
                    lock (MessageQueue)
                    {
                        Message = MessageQueue.Dequeue();
                        if (Message != null)
                        {
                            Write(Message);
                        }
                    }
                }
                else
                {
                    if (ThreadState)
                    {
                        Thread.Sleep(1);
                    }
                    else
                    {
                        CloseFile();
                    }
                }
            }
        }
        private void CloseFile()
        {
            if (sw != null)
            {
                sw.Flush();
                sw.Close();
                sw.Dispose();
                sw = null;
            }
        }
        private void OpenFile()
        {
            string FilePath = ConfigurationManager.AppSettings["LogFilePath"].ToString() + "\\Log";
            string FileName = "Log - " + DateTime.Now.ToString("yyyy-MM-dd") + ".log";

            if (!Directory.Exists(FilePath))
                Directory.CreateDirectory(FilePath);
            sw = new StreamWriter(FilePath + "\\" + FileName, true, Encoding.UTF8);
        }
        public void Dispose()
        {
            ThreadState = false;
        }    }
}
